home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / mpeg_play-2.1 / 2x2.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  9KB  |  382 lines

  1. /*
  2.  * 2x2.c --
  3.  *
  4.  *      Procedures concerned with 2x2 dithering.
  5.  *
  6.  */
  7.  
  8. /*
  9.  * Copyright (c) 1995 The Regents of the University of California.
  10.  * All rights reserved.
  11.  * 
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose, without fee, and without written agreement is
  14.  * hereby granted, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  * 
  17.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  18.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  19.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  20.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21.  * 
  22.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  23.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  24.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  25.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  26.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  27.  */
  28.  
  29. #include "video.h"
  30. #include "dither.h"
  31. #include "proto.h"
  32.  
  33. #define RAND_ERR_RANGE 7
  34. #define RAND_ERR_SUBVAL 3
  35.  
  36. /* Array containing actual pixel values for each possible 2x2 dither pattern. */
  37.  
  38. static unsigned char *dith_a;
  39.  
  40. /* Arrays mapping lum, cr, and cb values to portions of dither pattern code. 
  41.    The addtion of one value from each array yields a valid dither pattern
  42.    code.
  43. */
  44.  
  45. static int lval_a[256+RAND_ERR_RANGE-1];
  46. static int rval_a[256+RAND_ERR_RANGE-1];
  47. static int bval_a[256+RAND_ERR_RANGE-1];
  48.  
  49. /* Range of possible dither patterns in each channel. */
  50.  
  51. #define L_DITH_RANGE (((LUM_RANGE-1)*4)+1)
  52. #define CR_DITH_RANGE (((CR_RANGE-1)*4)+1)
  53. #define CB_DITH_RANGE (((CB_RANGE-1)*4)+1)
  54.  
  55. /* Arrays of random error terms added to break up contours. */
  56.  
  57. static int *randval_a;
  58. static int **randptr_a;
  59.  
  60.  
  61. /*
  62.  *--------------------------------------------------------------
  63.  *
  64.  *  Init2x2Dither--
  65.  *
  66.  *    Initializes structures used for 2x2 dithering.
  67.  *
  68.  * Results:
  69.  *    None.
  70.  *
  71.  * Side effects:
  72.  *    None.
  73.  *
  74.  *--------------------------------------------------------------
  75.  */
  76.  
  77. void
  78. Init2x2Dither()
  79. {  
  80.   unsigned char *dith_ca;
  81.   int numcodes;
  82.   int l_range, cr_range, cb_range;
  83.   int p1, p2, p3, p4;
  84.   int l_dith, cr_dith, cb_dith;
  85.   int big_part, small_part;
  86.   int i, j;
  87.  
  88.   l_range = L_DITH_RANGE;
  89.   cr_range = CR_DITH_RANGE;
  90.   cb_range = CB_DITH_RANGE;
  91.  
  92.   numcodes =  l_range * cr_range * cb_range;
  93.  
  94.   dith_a = (unsigned char *) malloc(numcodes*4);
  95.  
  96.   dith_ca =  dith_a;
  97.  
  98.   for (i=0; i<numcodes; i++) {
  99.     l_dith = i  % l_range;
  100.  
  101.     big_part = l_dith / 4;
  102.     small_part = l_dith % 4;
  103.  
  104.     p1 = big_part + ((small_part > 0) ? 1 : 0);
  105.     p2 = big_part + ((small_part > 2) ? 1 : 0);
  106.     p3 = big_part;
  107.     p4 = big_part + ((small_part > 1) ? 1 : 0);
  108.  
  109.     p1 *= CR_RANGE * CB_RANGE;
  110.     p2 *= CR_RANGE * CB_RANGE;
  111.     p3 *= CR_RANGE * CB_RANGE;
  112.     p4 *= CR_RANGE * CB_RANGE;
  113.  
  114.     cr_dith = (i/l_range) % cr_range;
  115.  
  116.     big_part = cr_dith / 4;
  117.     small_part = cr_dith % 4;
  118.  
  119.     p1 += (big_part + ((small_part > 0) ? 1 : 0))*CB_RANGE;
  120.     p2 += (big_part + ((small_part > 2) ? 1 : 0))*CB_RANGE;
  121.     p3 += (big_part)*CB_RANGE;
  122.     p4 += (big_part + ((small_part > 1) ? 1 : 0))*CB_RANGE;
  123.  
  124.     cb_dith = (i/(cr_range*l_range)) % cb_range;
  125.  
  126.     big_part = cb_dith / 4;
  127.     small_part = cb_dith % 4;
  128.  
  129.     p1 += (big_part + ((small_part > 0) ? 1 : 0));
  130.     p2 += (big_part + ((small_part > 2) ? 1 : 0));
  131.     p3 += (big_part);
  132.     p4 += (big_part + ((small_part > 1) ? 1 : 0));
  133.  
  134.     *dith_ca++ = p1;
  135.     *dith_ca++ = p2;
  136.     *dith_ca++ = p3;
  137.     *dith_ca++ = p4;
  138.   }
  139.  
  140.   for (i=RAND_ERR_SUBVAL; i<256+RAND_ERR_SUBVAL; i++) {
  141.     j = i-RAND_ERR_SUBVAL;
  142.     lval_a[i] = (j * L_DITH_RANGE)/256;
  143.     rval_a[i] = (j * CR_DITH_RANGE)/256;
  144.     bval_a[i] = (j * CB_DITH_RANGE)/256;
  145.  
  146.     bval_a[i] *= CR_DITH_RANGE * L_DITH_RANGE * 4;
  147.     rval_a[i] *= L_DITH_RANGE * 4;
  148.     lval_a[i] *= 4;
  149.   }
  150.  
  151.   for (i=0; i<RAND_ERR_SUBVAL; i++) {
  152.     lval_a[i] = lval_a[RAND_ERR_SUBVAL];
  153.     rval_a[i] = rval_a[RAND_ERR_SUBVAL];
  154.     bval_a[i] = bval_a[RAND_ERR_SUBVAL];
  155.   }
  156.  
  157.    for(i=256+RAND_ERR_SUBVAL; i<256+RAND_ERR_RANGE-1; i++) {
  158.      lval_a[i] = lval_a[255+RAND_ERR_SUBVAL];
  159.      rval_a[i] = rval_a[255+RAND_ERR_SUBVAL];
  160.      bval_a[i] = bval_a[255+RAND_ERR_SUBVAL];
  161.    }
  162. }
  163.  
  164.  
  165. /*
  166.  *--------------------------------------------------------------
  167.  *
  168.  * RandInit --
  169.  *
  170.  *    Initializes the random values used for 2x2 dithering.
  171.  *
  172.  * Results:
  173.  *    randval_a filled with random values.
  174.  *      randptr_a filled with random pointers to random value arrays.
  175.  *
  176.  * Side effects:
  177.  *      None.
  178.  *
  179.  *--------------------------------------------------------------
  180.  */
  181.  
  182. void RandInit(h, w)
  183.      int h, w;
  184. {
  185.   int i;
  186.  
  187.   randval_a = (int *) malloc(w*5*sizeof(int));
  188.   randptr_a = (int **) malloc(h*sizeof(int *));
  189.  
  190. #ifdef NO_LRAND48
  191.   for (i=0; i<w*5; i++) {
  192.     long int random();
  193.  
  194.     randval_a[i] = random() % RAND_ERR_RANGE;
  195.   }
  196.  
  197.   for (i=0; i<h; i++) {
  198.     long int random();
  199.  
  200.     randptr_a[i] = randval_a + (random() % (w*2));
  201.   }
  202. #else /* NO_LRAND48 */
  203.  
  204.   for (i=0; i<w*5; i++) {
  205.     long int lrand48();
  206.     
  207.     randval_a[i] = lrand48() % RAND_ERR_RANGE;
  208.   }
  209.   
  210.   for (i=0; i<h; i++) {
  211.     long int lrand48();
  212.  
  213.     randptr_a[i] = randval_a + (lrand48() % (w*2));
  214.   }
  215. #endif
  216.   
  217. }
  218.  
  219.  
  220. /*
  221.  *--------------------------------------------------------------
  222.  *
  223.  *  PostInit2x2Dither--
  224.  *
  225.  *    Remaps color numbers in dither patterns to actual pixel
  226.  *      values allocated by the X server.
  227.  *
  228.  * Results:
  229.  *      None.
  230.  *
  231.  * Side effects:
  232.  *      None.
  233.  *
  234.  *--------------------------------------------------------------
  235.  */
  236.  
  237. void
  238. PostInit2x2Dither() 
  239. {
  240.   unsigned char *dith_ca;
  241.   int i;
  242.  
  243.   dith_ca = dith_a;
  244.  
  245.   for (i=0; i < (L_DITH_RANGE * CR_DITH_RANGE * CB_DITH_RANGE); i++) {
  246.     
  247.     *dith_ca = pixel[*dith_ca];
  248.     dith_ca++;
  249.     *dith_ca = pixel[*dith_ca];
  250.     dith_ca++;
  251.     *dith_ca = pixel[*dith_ca];
  252.     dith_ca++;
  253.     *dith_ca = pixel[*dith_ca];
  254.     dith_ca++;
  255.   }
  256. }
  257.  
  258.  
  259. /*
  260.  *--------------------------------------------------------------
  261.  *
  262.  * Twox2DitherImage --
  263.  *
  264.  *    Dithers lum, cr, and cb channels togethor using predefined
  265.  *      and computed 2x2 dither patterns. Each possible combination of
  266.  *      lum, cr, and cb values combines to point to a particular dither
  267.  *      pattern (2x2) which is used to represent the pixel. This assumes
  268.  *      That the display plane is 4 times larger than the lumianance 
  269.  *      plane. 
  270.  *
  271.  * Results:
  272.  *      None.
  273.  *
  274.  * Side effects:
  275.  *      None.
  276.  *
  277.  *--------------------------------------------------------------
  278.  */
  279.  
  280. void 
  281. Twox2DitherImage(lum, cr, cb, out, h, w)
  282.     unsigned char *lum;
  283.     unsigned char *cr;
  284.     unsigned char *cb;
  285.     unsigned char *out;
  286.     int w, h;
  287. {
  288.   int i, j;
  289.   unsigned short *o1, *o2, *o3, *o4;
  290.   unsigned char *l1, *l2, *base;
  291.   unsigned char B, R;
  292.   unsigned short *dith_ca;
  293.   int big_adv = 3*w;
  294.   int b_val, r_val, l_val;
  295.   static int first = 1;
  296.  
  297.   if (first) {
  298.     RandInit(h, w);
  299.     first = 0;
  300.   }
  301.  
  302.   o1 = (unsigned short *)out;
  303.   o2 = (unsigned short *)(out+(2*w));
  304.   o3 = (unsigned short *)(out+(4*w));
  305.   o4 = (unsigned short *)(out+(6*w));
  306.   l1 = lum;
  307.   l2 = lum+w;
  308.  
  309.   for (i=0; i<h; i+=2) {
  310.     for(j=0; j<w; j+= 4) {
  311.  
  312.       B = cb[0];
  313.       b_val = bval_a[B];
  314.       R = cr[0];
  315.       r_val = rval_a[R];
  316.       base = dith_a + b_val + r_val;
  317.  
  318.       l_val = lval_a[l1[0]];
  319.       dith_ca = (unsigned short *)(base + l_val);
  320.       o1[0] = dith_ca[0];
  321.       o2[0] = dith_ca[1];
  322.  
  323.       l_val = lval_a[l1[1]];
  324.       dith_ca = (unsigned short *)(base + l_val);
  325.       o1[1] = dith_ca[0];
  326.       o2[1] = dith_ca[1];
  327.  
  328.       l_val = lval_a[l2[0]];
  329.       dith_ca = (unsigned short *)(base + l_val);
  330.       o3[0] = dith_ca[0];
  331.       o4[0] = dith_ca[1];
  332.  
  333.       l_val = lval_a[l2[1]];
  334.       dith_ca = (unsigned short *)(base + l_val);
  335.       o3[1] = dith_ca[0];
  336.       o4[1] = dith_ca[1];
  337.  
  338.       B = cb[1];
  339.       b_val = bval_a[B];
  340.       R = cr[1];
  341.       r_val = rval_a[R];
  342.       base = dith_a + b_val + r_val;
  343.  
  344.       l_val = lval_a[l1[2]];
  345.       dith_ca = (unsigned short *)(base + l_val);
  346.       o1[2] = dith_ca[0];
  347.       o2[2] = dith_ca[1];
  348.  
  349.       l_val = lval_a[l1[3]];
  350.       dith_ca = (unsigned short *)(base + l_val);
  351.       o1[3] = dith_ca[0];
  352.       o2[3] = dith_ca[1];
  353.  
  354.       l_val = lval_a[l2[2]];
  355.       dith_ca = (unsigned short *)(base + l_val);
  356.       o3[2] = dith_ca[0];
  357.       o4[2] = dith_ca[1];
  358.  
  359.       l_val = lval_a[l2[3]];
  360.       dith_ca = (unsigned short *)(base + l_val);
  361.       o3[3] = dith_ca[0];
  362.       o4[3] = dith_ca[1];
  363.  
  364.       o1 += 4;
  365.       o2 += 4;
  366.       o3 += 4;
  367.       o4 += 4;
  368.       l1 += 4;
  369.       l2 += 4;
  370.       cb += 2;
  371.       cr += 2;
  372.     }    
  373.  
  374.     l1 += w;
  375.     l2 += w;
  376.     o1 += big_adv;
  377.     o2 += big_adv;
  378.     o3 += big_adv;
  379.     o4 += big_adv;
  380.   }
  381. }
  382.